<template>
	<div class="container">
		<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
					:leave-active-class="proxy?.animate.searchAnimate.leave">
			<div v-show="showSearch" class="search">
				<el-form ref="queryFormRef" :inline="true" :model="queryParams" label-width="68px">
					<el-form-item label="标题" prop="noticeTitle">
						<el-input v-model="queryParams.noticeTitle" clearable placeholder="请输入标题"
								  style="width: 240px" @keyup.enter="handleQuery" />
					</el-form-item>
					<el-form-item label="类型" prop="noticeType">
						<el-select v-model="queryParams.noticeType" clearable placeholder="请选择类型"
								   style="width: 240px">
							<el-option
								v-for="dict in sys_notice_type"
								:key="dict.value"
								:label="dict.label"
								:value="dict.value"
							/>
						</el-select>
					</el-form-item>
					<el-form-item label="状态" prop="status">
						<el-select v-model="queryParams.status" clearable placeholder="请选择状态" style="width: 240px">
							<el-option
								v-for="dict in sys_notice_status"
								:key="dict.value"
								:label="dict.label"
								:value="dict.value"
							/>
						</el-select>
					</el-form-item>
					<el-form-item>
						<el-button icon="Search" type="primary" @click="handleQuery">搜索</el-button>
						<el-button icon="Refresh" @click="resetQuery">重置</el-button>
					</el-form-item>
				</el-form>
			</div>
		</transition>

		<el-card shadow="never">
			<template #header>
				<el-row :gutter="10" class="mb8">
					<el-col :span="1.5">
						<el-button v-hasPermi="['system:notice:add']" icon="Plus" plain type="primary"
								   @click="handleAdd">新增
						</el-button>
					</el-col>
					<el-col :span="1.5">
						<el-button v-hasPermi="['system:notice:edit']" :disabled="single" icon="Edit" plain
								   type="success"
								   @click="handleUpdate()">修改
						</el-button>
					</el-col>
					<el-col :span="1.5">
						<el-button v-hasPermi="['system:notice:remove']" :disabled="multiple" icon="Delete" plain
								   type="danger"
								   @click="handleDelete()">删除
						</el-button>
					</el-col>
					<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
				</el-row>
			</template>

			<el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
				<el-table-column align="center" type="selection" width="55" />
				<el-table-column v-if="false" align="center" label="公告ID" prop="noticeId" />
				<el-table-column align="center" label="序号" type="index" width="50">
					<template #default="scope">
						<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
					</template>
				</el-table-column>
				<el-table-column align="center" label="标题" prop="noticeTitle" />
				<el-table-column align="center" label="类型" prop="noticeType">
					<template #default="scope">
						<dict-tag :options="sys_notice_type" :value="scope.row.noticeType" />
					</template>
				</el-table-column>
				<el-table-column align="center" label="状态" prop="status">
					<template #default="scope">
						<dict-tag :options="sys_notice_status" :value="scope.row.status" />
					</template>
				</el-table-column>
				<el-table-column align="center" label="创建时间" prop="createTime" width="180">
					<template #default="scope">
						<span>{{ parseTime(scope.row.createTime) }}</span>
					</template>
				</el-table-column>
				<el-table-column align="center" label="备注" prop="remark" />
				<el-table-column align="center" class-name="small-padding fixed-width" label="操作">
					<template #default="scope">
						<el-tooltip content="修改" placement="top">
							<el-button v-hasPermi="['system:notice:edit']" icon="Edit" link type="primary"
									   @click="handleUpdate(scope.row)"></el-button>
						</el-tooltip>
						<el-tooltip content="删除" placement="top">
							<el-button v-hasPermi="['system:notice:remove']" icon="Delete" link type="primary"
									   @click="handleDelete(scope.row)"></el-button>
						</el-tooltip>
					</template>
				</el-table-column>
			</el-table>

			<pagination
				v-show="total>0"
				v-model:limit="queryParams.pageSize"
				v-model:page="queryParams.pageNum"
				:total="total"
				@pagination="getList"
			/>
		</el-card>
		<!-- 添加或修改通知公告对话框抽屉 -->
		<el-drawer v-model="dialog.visible" :title="dialog.title" append-to-body size="50%">
			<el-form ref="noticeFormRef" :model="form" :rules="rules" label-width="120px">
				<el-form-item label="标题" prop="noticeTitle">
					<el-input v-model="form.noticeTitle" placeholder="请输入标题" />
				</el-form-item>
				<el-form-item label="类型" prop="noticeType">
					<el-select v-model="form.noticeType" placeholder="请选择类型">
						<el-option
							v-for="dict in sys_notice_type"
							:key="dict.value"
							:label="dict.label"
							:value="dict.value"
						></el-option>
					</el-select>
				</el-form-item>
				<el-form-item v-if="dialog.title==='修改通知公告'" label="状态" prop="status">
					<el-radio-group v-model="form.status">
						<el-radio
							v-for="dict in sys_notice_status"
							:key="dict.value"
							:label="dict.value"
						>{{ dict.label }}
						</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item v-if="dialog.title==='添加通知公告'" label="可见范围" prop="userIcon">
					<el-select v-model="form.userIcon" placeholder="请选择类型">
						<el-option
							v-for="dict in sys_see"
							:key="dict.value"
							:label="dict.label"
							:value="dict.value"
						></el-option>
					</el-select>
				</el-form-item>
				<el-form-item v-if="form.userIcon==='1'" label="可见人员" prop="person" style="font-weight: bold">
					<div style="display: flex;flex-direction: column;">
						<el-button icon="Search" style="width: 100px" type="primary" @click="handleSelectUser">选择
						</el-button>
						<div style="display: flex; flex-wrap: wrap;">
							<el-tag v-for="(item,index) in userNames" :key="item.userId" closable
									style="margin: 10px 10px 0 0"
									type="primary"
									@close="handleClose(item.userId, index)">
								{{ item.nickName }}
							</el-tag>
						</div>
					</div>
				</el-form-item>
				<el-form-item label="内容">
					<editor v-model="form.noticeContent" :min-height="192" />
				</el-form-item>
				<el-form-item label="备注" prop="remark">
					<el-input v-model="form.remark" placeholder="请输入备注" />
				</el-form-item>
			</el-form>
			<template #footer>
				<div class="dialog-footer">
					<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
					<el-button @click="cancel">取 消</el-button>
				</div>
			</template>
		</el-drawer>
		<!-- 部门选择对话框 -->
		<el-dialog v-model="selectDialog.visible" :title="selectDialog.title" append-to-body width="50%">
			<div style="display: flex;justify-content: center">
				<div class="deptStyle">
					<el-tree
						ref="deptRef"
						:check-strictly="true"
						:data="deptOptions"
						:props="defaultProps"
						class="tree-no-border"
						default-expand-all
						empty-text="加载中，请稍后"
						node-key="id"
						show-checkbox
						@check="getCheckedNodes"
					/>
				</div>
				<div class="employeeStyle">
					<el-table ref="userTable" :data="checkUserList" border @selection-change="selectionUserChange">
						<el-table-column align="center" type="selection" width="55" />
						<el-table-column align="center" label="用户" prop="nickName" />
						<el-table-column align="center" label="归属部门" prop="dept.deptName" />
					</el-table>
				</div>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button :loading="buttonLoading" type="primary" @click="confirmUserSelection">确 定</el-button>
					<el-button @click="cancelCheck">取 消</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script lang="ts" name="Notice" setup>
import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice";
import { treeselect } from "@/api/system/dept";
import { userList } from "@/api/system/user";
import { NoticeVO, NoticeQuery, NoticeForm } from "@/api/system/notice/types";
import { parseTime } from "@/utils/lychee";
import { ElTable } from "element-plus";

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const {
	sys_notice_status,
	sys_notice_type,
	sys_see,
} = toRefs<any>(proxy?.useDict("sys_notice_status", "sys_notice_type", "sys_see"));

// 通知公告集合
const noticeList = ref<NoticeVO[]>([]);
// 按钮加载
const buttonLoading = ref(false);
// 表格加载
const loading = ref(true);
// 显示搜索框
const showSearch = ref(true);
// 多选框选中集合
const ids = ref<Array<string | number>>([]);
const defaultProps = {
	children: "children",
	label: "label",
};
// 创建一个 ref 来引用 el-tree 组件实例
const deptRef = ref();

// 部门列表
const deptOptions = ref<any>();
//已选用户集合
const checkUserList = ref<any[]>([]);
//已选用户备用集合
const checkHisUserList = ref<any[]>([]);
// 多选框选中集合
const userIds = ref<Array<string | number>>([]);
// 选中的用户集合
const userNames = ref<any[]>([]);

const single = ref(true);
const multiple = ref(true);
const total = ref(0);

//查询条件参数表单
const queryFormRef = ref<ElFormInstance>();
// 消息相关表单
const noticeFormRef = ref<ElFormInstance>();
// 表格引用
const userTable = ref<InstanceType<typeof ElTable> | null>(null);

// 手动点击标志
const click = ref(true);


//新增弹出层控制变量
const dialog = reactive<DialogOption>({
	visible: false,
	title: "",
});

//部门选择弹出层控制变量
const selectDialog = reactive<DialogOption>({
	visible: false,
	title: "",
});

const initFormData: NoticeForm = {
	noticeId: undefined,
	userIcon: "0",
	userIds: [] as (string | number)[],
	noticeTitle: undefined,
	noticeType: undefined,
	noticeContent: undefined,
	status: undefined,
	createTime: undefined,
	remark: undefined,
};
const data = reactive<PageData<NoticeForm, NoticeQuery>>({
	form: { ...initFormData },
	queryParams: {
		pageNum: 1,
		pageSize: 10,
		noticeTitle: undefined,
		noticeType: undefined,
		status: undefined,
		params: {},
	},
	rules: {
		noticeTitle: [
			{ required: true, message: "标题不能为空", trigger: "blur" },
		], noticeType: [
			{ required: true, message: "类型不能为空", trigger: "change" },
		],
	},
});

const { queryParams, form, rules } = toRefs(data);

/** 查询通知公告列表 */
const getList = async () => {
	loading.value = true;
	const res = await listNotice(queryParams.value);
	noticeList.value = res.rows;
	total.value = res.total;
	loading.value = false;
};

/** 取消按钮 */
const cancel = () => {
	reset();
	dialog.visible = false;
};

/** 表单重置 */
const reset = () => {
	form.value = { ...initFormData };
	noticeFormRef.value?.resetFields();
	checkUserList.value = [];
	userIds.value = [];
	userNames.value = [];
};

/** 搜索按钮操作 */
const handleQuery = () => {
	queryParams.value.pageNum = 1;
	getList();
};

/** 重置按钮操作 */
const resetQuery = () => {
	queryFormRef.value?.resetFields();
	handleQuery();
};

/** 多选框选中数据 */
const handleSelectionChange = (selection: NoticeVO[]) => {
	ids.value = selection.map(item => item.noticeId);
	single.value = selection.length != 1;
	multiple.value = !selection.length;
};

/** 选择用户弹出层 */
const handleSelectUser = () => {
	selectDialog.visible = true;
	selectDialog.title = "选择员工/部门";
	getTreeSelect();
};

/** 查询部门下拉树结构 */
const getTreeSelect = () => {
	treeselect({ status: 0 }).then((response: any) => {
		deptOptions.value = response.data;
		// 使用 nextTick 确保DOM更新完成
		nextTick(() => {
			if (deptRef.value) {
				// 清除所有已有的选中状态
				deptRef.value.setCheckedKeys([]);
				// 设置选中的节点，假设checkList包含的是节点的'id'属性
				const filteredCheckUserList = checkUserList.value.filter(item =>
					userIds.value.includes(item.userId),
				);
				const checkedKeys = filteredCheckUserList.map(item => item.deptId);
				deptRef.value.setCheckedKeys(checkedKeys);
			}
		});
	});
};

/** 选中节点数据 */
const getCheckedNodes = (currentNode: any) => {
	if (deptRef.value) {
		// 获取选中的节点数据
		const checkedNodes = deptRef.value.getCheckedNodes();
		// 判断是勾选还是取消勾选
		if (checkedNodes.some((node: any) => node.id === currentNode.id)) {//勾选
			getUsers(currentNode.id);
		} else {//取消勾选
			// 从checkUserList中移除deptId等于currentNode.id的所有用户
			click.value = false;
			checkUserList.value = checkUserList.value.filter((user: any) => user.deptId !== currentNode.id);
			nextTick(() => {
				if (userTable.value) {
					const tableInstance = userTable.value;
					checkUserList.value.forEach(row => {
						click.value = false;
						tableInstance.toggleRowSelection(row, true);
						click.value = true;
					});
				}
			});
		}
	}
};

/** 获取用户数据 */
const getUsers = (id: any) => {
	let params = {
		deptId: id,
	};
	userList(params).then(res => {
		let userList = res.data;
		userList.forEach((item: any) => {
			if (!checkUserList.value.find(i => i.userId === item.userId)) {
				checkUserList.value.push(item);
			}
		});
		nextTick(() => {
			if (userTable.value) {
				const tableInstance = userTable.value;
				checkUserList.value.forEach(row => {
					click.value = false;
					if (row.deptId === id) {
						tableInstance.toggleRowSelection(row, true);
					}

					click.value = true;
				});
			}
		});
	});
};

/** 选中用户数据 */
const selectionUserChange = (selection: any) => {
	userIds.value = selection.map((item: any) => item.userId);
	// 使用 nextTick 确保DOM更新完成
	if (click.value === true) {
		nextTick(() => {
			if (deptRef.value) {
				// 清除所有已有的选中状态
				deptRef.value.setCheckedKeys([]);
				// 设置选中的节点
				const filteredCheckUserList = checkUserList.value.filter(item =>
					userIds.value.includes(item.userId),
				);
				const checkedKeys = filteredCheckUserList.map(item => item.deptId);
				deptRef.value.setCheckedKeys(checkedKeys);
				if (filteredCheckUserList.length === 0) {
					checkUserList.value = [];
				}
			}
		});
	}

};

/** 确认用户选择 */
const confirmUserSelection = () => {
	//如果未选择用户将情况用户选项
	if (userIds.value.length === 0) {
		proxy?.$modal.msgError("请选择用户");
		return;
	}
	//同步表单数据
	form.value.userIds = userIds.value;
	//填充tag用户数据
	checkUserList.value.forEach((item: any) => {
		// 如果存在，找到或创建该用户的记录并添加到userNames
		const existingUser = userNames.value.find(user => user.userId === item.userId);
		if (!existingUser) {
			userNames.value.push({
				userId: item.userId,
				nickName: item.nickName,
			});
		}
	});
	// 备用数据集同步
	checkHisUserList.value = checkUserList.value;
	// 处理需要移除的用户
	userNames.value = userNames.value.filter(user =>
		userIds.value.includes(user.userId),
	);
	//关闭弹出层
	selectDialog.visible = false;
};

/** 关闭用户标签 */
const handleClose = (tag: any, index: number) => {
	// 在移除用户前保存选择状态
	const currentSelectedRows = userTable.value?.getSelectionRows().map((row: any) => row.userId) || [];
	// 从userNames中移除该项
	userNames.value.splice(index, 1);
	// 从userIds中移除对应的userId
	userIds.value = userIds.value.filter(id => id !== tag);
	// 从表单的userIds中移除对应的userId
	if (form.value && form.value.userIds) {
		// 从表单的userIds中移除对应的userId
		form.value.userIds = form.value.userIds.filter(id => id !== tag);
	} else {
		console.warn("form 或 form.userIds 未定义");
	}
	// 从checkUserList中移除该项
	checkUserList.value = checkUserList.value.filter(user => user.userId !== tag);
	checkHisUserList.value = checkUserList.value;
	// 确保DOM更新完成后再恢复选择状态
	nextTick(() => {
		if (userTable.value) {
			const tableInstance = userTable.value;
			tableInstance.clearSelection();
			checkUserList.value.forEach(row => {
				if (currentSelectedRows.includes(row.userId)) {
					tableInstance.toggleRowSelection(row, true);
				}
			});
		}
	});
};


/** 关闭选择用户弹出层 */
const cancelCheck = () => {
	selectDialog.visible = false;
	checkUserList.value = checkHisUserList.value;
	// 确保DOM更新完成后再恢复选择状态
	nextTick(() => {
		if (userTable.value) {
			const tableInstance = userTable.value;
			tableInstance.clearSelection();
			// 首先将 userNames.value 转换为仅包含 userId 的集合，以便快速查找
			const userIds = new Set(userNames.value.map(user => user.userId));
			// 过滤出那些在 checkUserList 中且 userId 存在于 userNames 中的对象
			const filteredCheckUserList = checkUserList.value.filter(row => userIds.has(row.userId));
			// 对过滤后的列表进行操作
			filteredCheckUserList.forEach(row => {
				tableInstance.toggleRowSelection(row, true);
			});
		}
	});
};

/** 新增按钮操作 */
const handleAdd = () => {
	reset();
	dialog.visible = true;
	dialog.title = "添加通知公告";
};

/** 修改按钮操作 */
const handleUpdate = async (row?: NoticeVO) => {
	reset();
	const _noticeId = row?.noticeId || ids.value[0];
	const res = await getNotice(_noticeId);
	Object.assign(form.value, res.data);
	dialog.visible = true;
	dialog.title = "修改通知公告";
};

/** 提交按钮 */
const submitForm = () => {
	if (form.value?.userIcon === "1" && form.value?.userIds?.length === 0) {
		proxy?.$modal.msgError("未选择可见人员");
		return;
	}
	noticeFormRef.value?.validate(async (valid: boolean) => {
		if (valid) {
			buttonLoading.value = true;
			if (form.value.noticeId) {
				await updateNotice(form.value).finally(() => buttonLoading.value = false);
			} else {
				await addNotice(form.value).finally(() => buttonLoading.value = false);
			}
			proxy?.$modal.msgSuccess("修改成功");
			dialog.visible = false;
			await getList();
		}
	});
};

/** 删除按钮操作 */
const handleDelete = async (row?: NoticeVO) => {
	const _noticeIds = row?.noticeId || ids.value;
	await proxy?.$modal.confirm("是否确认删除通知公告编号为\"" + _noticeIds + "\"的数据项？").finally(() => loading.value = false);
	await delNotice(_noticeIds);
	proxy?.$modal.msgSuccess("删除成功");
	await getList();
};


onMounted(() => {
	getList();
});
</script>

<style>
.deptStyle {
	width: 50%;
	min-height: 500px;
	border: 1px #e5e6e7 solid;
	margin-right: 10px
}

.employeeStyle {
	width: 50%;
	min-height: 500px;
}
</style>
